// input.cpp
#define _WIN32_WINNT 0x0500

#include "internal.h"
#include <wgal.h>
#include <wgal/input.h>

#define WGAL_KEYCODE_COUNT		0x7C

namespace
{	
	WGALBool prevKeyInfo[WGAL_KEYCODE_COUNT] = {0,};
	WGALBool keyInfo[WGAL_KEYCODE_COUNT] = {0,0};
	POINT cursorPos = {0,};
	WGALUInt32 vKeyTable[WGAL_KEYCODE_COUNT] =
	{
		VK_LBUTTON,		// 0x00 : WGAL_KC_LBUTTON
		VK_RBUTTON,		// 0x01 : WGAL_KC_RBUTTON
		VK_MBUTTON,		// 0x02 : WGAL_KC_MBUTTON
		VK_XBUTTON1,	// 0x03 : WGAL_KC_XBUTTON1
		VK_XBUTTON2,	// 0x04 : WGAL_KC_XBUTTON2
		VK_BACK,		// 0x05 : WGAL_KC_BACKSPACE
		VK_TAB,			// 0x06 : WGAL_KC_TAB
		VK_RETURN,		// 0x07 : WGAL_KC_RETURN
		VK_SHIFT,		// 0x08 : WGAL_KC_SHIFT
		VK_CONTROL,		// 0x09 : WGAL_KC_CTRL
		VK_MENU,		// 0x0A : WGAL_KC_ALT
		VK_PAUSE,		// 0x0B : WGAL_KC_PAUSE
		VK_CAPITAL,		// 0x0C : WGAL_KC_CAPSLOCK
		VK_ESCAPE,		// 0x0D : WGAL_KC_ESCAPE
		VK_SPACE,		// 0x0E : WGAL_KC_SPACE
		VK_PRIOR,		// 0x0F : WGAL_KC_PAGEUP
		VK_NEXT,		// 0x10 : WGAL_KC_PAGEDOWN
		VK_END,			// 0x11 : WGAL_KC_END
		VK_HOME,		// 0x12 : WGAL_KC_HOME
		VK_LEFT,		// 0x13 : WGAL_KC_LEFT
		VK_UP,			// 0x14 : WGAL_KC_UP
		VK_RIGHT,		// 0x15 : WGAL_KC_RIGHT
		VK_DOWN,		// 0x16 : WGAL_KC_DOWN
		VK_SNAPSHOT,	// 0x17 : WGAL_KC_PRINTSCRN
		VK_INSERT,		// 0x18	: WGAL_KC_INSERT
		VK_DELETE,		// 0x19 : WGAL_KC_DELETE
		0x30,			// 0x1A : WGAL_KC_0
		0x31,			// 0x1B : WGAL_KC_1
		0x32,			// 0x1C : WGAL_KC_2
		0x33,			// 0x1D : WGAL_KC_3
		0x34,			// 0x1E : WGAL_KC_4
		0x35,			// 0x1F : WGAL_KC_5
		0x36,			// 0x20 : WGAL_KC_6
		0x37,			// 0x21 : WGAL_KC_7
		0x38,			// 0x22 : WGAL_KC_8
		0x39,			// 0x23 : WGAL_KC_9
		0x41,			// 0x24 : WGAL_KC_A
		0x42,			// 0x25 : WGAL_KC_B
		0x43,			// 0x26 : WGAL_KC_C
		0x44,			// 0x27 : WGAL_KC_D
		0x45,			// 0x28 : WGAL_KC_E
		0x46,			// 0x29 : WGAL_KC_F
		0x47,			// 0x2A : WGAL_KC_G
		0x48,			// 0x2B : WGAL_KC_H
		0x49,			// 0x2C : WGAL_KC_I
		0x4A,			// 0x2D : WGAL_KC_J
		0x4B,			// 0x2E : WGAL_KC_K
		0x4C,			// 0x2F : WGAL_KC_L
		0x4D,			// 0x30 : WGAL_KC_M
		0x4E,			// 0x31 : WGAL_KC_N
		0x4F,			// 0x32 : WGAL_KC_O
		0x50,			// 0x33 : WGAL_KC_P
		0x51,			// 0x34 : WGAL_KC_Q
		0x52,			// 0x35 : WGAL_KC_R
		0x53,			// 0x36 : WGAL_KC_S
		0x54,			// 0x37 : WGAL_KC_T
		0x55,			// 0x38 : WGAL_KC_U
		0x56,			// 0x39 : WGAL_KC_V
		0x57,			// 0x3A : WGAL_KC_W
		0x58,			// 0x3B : WGAL_KC_X
		0x59,			// 0x3C : WGAL_KC_Y
		0x5A,			// 0x3D : WGAL_KC_Z
		VK_LWIN,		// 0x3E : WGAL_KC_LWINDOWS
		VK_RWIN,		// 0x3F : WGAL_KC_RWINDOWS
		VK_LSHIFT,		// 0x40 : WGAL_KC_LSHIFT
		VK_RSHIFT,		// 0x41 : WGAL_KC_RSHIFT
		VK_LCONTROL,	// 0x42 : WGAL_KC_LCTRL
		VK_RCONTROL,	// 0x43 : WGAL_KC_RCTRL
		VK_LMENU,		// 0x44 : WGAL_KC_LALT
		VK_RMENU,		// 0x45 : WGAL_KC_RALT
		VK_F1,			// 0x46 : WGAL_KC_F1
		VK_F2,			// 0x47 : WGAL_KC_F2
		VK_F3,			// 0x48 : WGAL_KC_F3
		VK_F4,			// 0x49 : WGAL_KC_F4
		VK_F5,			// 0x4A : WGAL_KC_F5
		VK_F6,			// 0x4B : WGAL_KC_F6
		VK_F7,			// 0x4C : WGAL_KC_F7
		VK_F8,			// 0x4D : WGAL_KC_F8
		VK_F9,			// 0x4E : WGAL_KC_F9
		VK_F10,			// 0x4F : WGAL_KC_F10
		VK_F11,			// 0x50 : WGAL_KC_F11
		VK_F12,			// 0x51 : WGAL_KC_F12
		VK_F13,			// 0x52 : WGAL_KC_F13
		VK_F14,			// 0x53 : WGAL_KC_F14
		VK_F15,			// 0x54 : WGAL_KC_F15
		VK_F16,			// 0x55 : WGAL_KC_F16
		VK_F17,			// 0x56 : WGAL_KC_F17
		VK_F18,			// 0x57 : WGAL_KC_F18
		VK_F19,			// 0x58 : WGAL_KC_F19
		VK_F20,			// 0x59 : WGAL_KC_F20
		VK_F21,			// 0x5A : WGAL_KC_F21
		VK_F22,			// 0x5B : WGAL_KC_F22
		VK_F23,			// 0x5C : WGAL_KC_F23
		VK_F24,			// 0x5D : WGAL_KC_F24
		VK_NUMPAD0,		// 0x5E : WGAL_KC_NUMPAD0
		VK_NUMPAD1,		// 0x5F : WGAL_KC_NUMPAD1
		VK_NUMPAD2,		// 0x60 : WGAL_KC_NUMPAD2
		VK_NUMPAD3,		// 0x61 : WGAL_KC_NUMPAD3
		VK_NUMPAD4,		// 0x62 : WGAL_KC_NUMPAD4
		VK_NUMPAD5,		// 0x63 : WGAL_KC_NUMPAD5
		VK_NUMPAD6,		// 0x64 : WGAL_KC_NUMPAD6
		VK_NUMPAD7,		// 0x65 : WGAL_KC_NUMPAD7
		VK_NUMPAD8,		// 0x66 : WGAL_KC_NUMPAD8
		VK_NUMPAD9,		// 0x67 : WGAL_KC_NUMPAD9
		VK_ADD,			// 0x68 : WGAL_KC_ADD
		VK_MULTIPLY,	// 0x69 : WGAL_KC_MULTIPLY
		VK_SEPARATOR,	// 0x6A : WGAL_KC_SEPARATOR
		VK_SUBTRACT,	// 0x6B : WGAL_KC_SUBTRACT
		VK_DECIMAL,		// 0x6C : WGAL_KC_DECIMAL
		VK_DIVIDE,		// 0x6D : WGAL_KC_DIVIDE
		VK_OEM_PLUS,	// 0x6E : WGAL_KC_PLUS
		VK_OEM_COMMA,	// 0x6F : WGAL_KC_COMMA
		VK_OEM_MINUS,	// 0x70 : WGAL_KC_MINUS
		VK_OEM_PERIOD,	// 0x71 : WGAL_KC_PERIOD
		VK_OEM_2,		// 0x72 : WGAL_KC_SLASH
		VK_OEM_3,		// 0x73 : WGAL_KC_TILDE
		VK_OEM_4,		// 0x74 : WGAL_KC_LBRACE
		VK_OEM_5,		// 0x75 : WGAL_KC_BACKSLASH
		VK_OEM_6,		// 0x76 : WGAL_KC_RBRACE
		VK_OEM_7,		// 0x77 : WGAL_KC_QUOTE
		VK_NUMLOCK,		// 0x78 : WGAL_KC_NUMLOCK
		VK_SCROLL,		// 0x79 : WGAL_KC_SCROLLLOCK
		VK_OEM_1,		// 0x7A : WGAL_KC_SEMICOLON
		VK_APPS,		// 0x7B : WGAL_KC_APPS
	};
};

WGALVoid wgalUpdateInputState()
{
	int i;
	WGALUInt32 * vk_ptr;

	if(!wgalIsActive())
		return;

	if(!GetSystemMetrics(SM_SWAPBUTTON))
	{
		// default
		vKeyTable[WGAL_KC_LBUTTON] = VK_LBUTTON;
		vKeyTable[WGAL_KC_RBUTTON] = VK_RBUTTON;
	}
	else
	{
		// swapped
		vKeyTable[WGAL_KC_LBUTTON] = VK_RBUTTON;
		vKeyTable[WGAL_KC_RBUTTON] = VK_LBUTTON;		
	}

	// save previous info
	for (i = 0, vk_ptr = vKeyTable;
		i != WGAL_KEYCODE_COUNT;
		i++, vk_ptr++)
	{
		prevKeyInfo[i] = keyInfo[i];
	}

	// update new info
	for (i = 0, vk_ptr = vKeyTable;
		i != WGAL_KEYCODE_COUNT;
		i++, vk_ptr++)
	{
		keyInfo[i] = (WGALBool)((USHORT)GetAsyncKeyState(*vk_ptr) >> 15);
	}

	// update key state
	GetCursorPos(&cursorPos);
	ScreenToClient(hWnd, &cursorPos);
}

WGALInt32 wgalGetKeyState(WGALUInt32 keyCode)
{
	if(keyCode < WGAL_KEYCODE_COUNT)
	{
		WGALUInt32 vKey = vKeyTable[keyCode];
		
		return 0;
	}

	return WGAL_INVALID_KEYCODE;
}

WGALBool wgalIsKeyUp(WGALUInt32 keyCode)
{
	if(keyCode < WGAL_KEYCODE_COUNT)
		return !keyInfo[keyCode];

	return WGAL_INVALID_KEYCODE;
}

WGALBool wgalIsKeyDown(WGALUInt32 keyCode)
{
	if(keyCode < WGAL_KEYCODE_COUNT)
		return keyInfo[keyCode];

	return WGAL_INVALID_KEYCODE;
}

WGALBool wgalIsKeyPressed(WGALUInt32 keyCode)
{
	if(keyCode < WGAL_KEYCODE_COUNT)
		return !prevKeyInfo[keyCode] && keyInfo[keyCode];

	return WGAL_INVALID_KEYCODE;
}

WGALBool wgalIsKeyReleased(WGALUInt32 keyCode)
{
	if(keyCode < WGAL_KEYCODE_COUNT)
		return prevKeyInfo[keyCode] && !keyInfo[keyCode];

	return WGAL_INVALID_KEYCODE;
}

WGALInt32 wgalGetCursorX()
{
	return (WGALInt32)cursorPos.x;
}

WGALInt32 wgalGetCursorY()
{
	return (WGALInt32)cursorPos.y;
}

WGALBool wgalGetCursorPos(WGALLocation *pos)
{
	if(pos)
	{
		pos->x = (WGALFloat)cursorPos.x;
		pos->y = (WGALFloat)cursorPos.y;

		return TRUE;
	}

	return FALSE;
}